package com.ref.demo12;

import java.lang.reflect.Field;

/**
 * @ClassName BeanUtil
 * @Description 定义一个工具类：BeanUtil,有以下三个方法：
 *     1、设置何意对象的属性值
 *     public static void setProperty(Object bean, String propertyName, Object value)
 *     2、获取任意对象的属性值
 *     public static Object getProperty(Object bean, String propertyName)
 *     3、复制某个对象的属性值到另一个对象中
 *     public static void copyProperties(Object source, Object target)
 * @Author Kx
 * @Date 2025/3/19 19:12
 * @Version 1.0
 */
public class BeanUtil {

    /**
     * @description: 设置何意对象的属性值
     * @author: Kx
     * @date: 2025/3/19 19:12
     * @param: [bean, propertyName, value]
     * @return: void
     **/
    public static void setProperty(Object bean, String propertyName, Object value){
        // 获取该对象
        Class<?> aClass = bean.getClass();

        try {
            // 获取该对象的属性
            Field declaredField = aClass.getDeclaredField(propertyName);

            // 设置属性的可访问性
            declaredField.setAccessible(true);

            // 设置属性的值
            declaredField.set(bean,value);

            System.out.println("设置属性值成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description: 获取任意对象的属性值
     * @author: Kx
     * @date: 2025/3/19 19:14
     * @param: [bean, propertyName]
     * @return: java.lang.Object
     **/
    public static Object getProperty(Object bean, String propertyName){
        // 获取该对象
        Class<?> aClass = bean.getClass();

        try {
            // 获取该对象的属性
            Field declaredField = aClass.getDeclaredField(propertyName);

            // 设置属性的可访问性
            declaredField.setAccessible(true);

            // 获取属性的值
            return declaredField.get(bean);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @description: 复制某个对象的属性值到另一个对象中
     * @author: Kx
     * @date: 2025/3/19 19:17
     * @param: [source, target]
     * @return: void
     **/
    public static void copyProperties(Object source, Object target){
        // 获取该对象
        Class<?> aClass = source.getClass();
        Class<?> aClass1 = target.getClass();

        // 获取第一个对象的所有属性名
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields){
            try {
                // 获取第二个对象的相同的属性名
                Field declaredField1 = aClass1.getDeclaredField(declaredField.getName());

                // 判断两个属性的类型是否相同
                if(declaredField.getType() == declaredField1.getType()){
                    // 设置属性的可访问性
                    declaredField.setAccessible(true);
                    declaredField1.setAccessible(true);

                    // 设置属性的值
                    declaredField1.set(target,declaredField.get(source));
                } else {
                    // 两个属性的类型不同,抛出异常
                   throw new IllegalArgumentException();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        // setProperty() 方法的测试
        Student student = new Student("1001","张三");
        BeanUtil.setProperty(student,"sNumber","1002");
        System.out.println(student);

        // 测试 getProperty() 方法
        Student student1 = new Student("1003", "李四");
        Object sNumber = BeanUtil.getProperty(student1, "sNumber");
        System.out.println(sNumber);

        // 测试 copyProperties() 方法
        BeanUtil.copyProperties(student,student1);
        System.out.println(student1);
    }
}
